package com.jingyanzi.finance.service.impl;

import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.jingyanzi.finance.dao.CashPayRecordMapper;
import com.jingyanzi.finance.domain.CashCashierDO;
import com.jingyanzi.finance.domain.CashPayRecordDO;
import com.jingyanzi.finance.domain.CashStatisticsDO;

import com.jingyanzi.finance.domain.CashTypeDO;
import com.jingyanzi.finance.domain.PayMethodDO;
import com.jingyanzi.finance.entity.CashCashier;
import com.jingyanzi.finance.entity.CashCashierExample;
import com.jingyanzi.finance.entity.CashPayRecord;
import com.jingyanzi.finance.entity.CashPayRecordExample;
import com.jingyanzi.finance.entity.CashPayRecordExample.Criteria;
import com.jingyanzi.finance.query.CashPayRecordQueryDO;
import com.jingyanzi.finance.query.CashPayRecordQueryDO1;
import com.jingyanzi.finance.query.KeyValueDO;
import com.jingyanzi.finance.result.ResultDO;
import com.jingyanzi.finance.result.ResultSupport;
import com.jingyanzi.finance.service.IPayRecordService;
import com.jingyanzi.finance.util.BeanUtilsExtends;
import com.jingyanzi.finance.util.ExportExcel;
import com.jingyanzi.privilege.domain.EmployeeDO;
import com.jingyanzi.privilege.factory.PrivilegeFactory;
import com.jingyanzi.privilege.service.IEmployeeService;
import com.jingyanzi.sys.domain.DictionariesDO;
import com.jingyanzi.sys.domain.service.ISettingService;
import com.jingyanzi.sys.factory.SysFactory;

@Service("payRecordService")
public class PayRecordServiceImpl extends BaseServiceImpl implements IPayRecordService {
	
	@Autowired
	private CashPayRecordMapper cashPayRecordMapper;
	
	private static Logger logger = Logger.getLogger(BillServiceImpl.class);
	
	private IEmployeeService getEmployeeService() {
		return PrivilegeFactory.getEmployeeService();
	}
	
	private ISettingService getSettingService() {
		return SysFactory.getISettingService();
	}

	public ResultDO add(CashPayRecordDO domain) {
		
		CashPayRecord entity = new CashPayRecord();
		
		ResultSupport result = BeanUtilsExtends.copy(entity, domain);
        if (!result.isSuccess())
        	return result;
        
        entity.setCreatetime(Calendar.getInstance().getTime());
        entity.setModifitime(entity.getCreatetime());
        entity.setIsDelete(1);
        int r = -1;
        
        try {
            r = cashPayRecordMapper.insert(entity);
        } catch (Exception e) {
        	logger.error(ResultSupport.SYSTEM_EXCEPTION_ERROR_MSG + e.getMessage());
        }
        
        if (r < 1) {
        	result.setSuccess(false);
        }
 
        result.setModel(ResultDO.FIRST_MODEL_KEY, entity.getId());
        return result;
	}

	public ResultDO modifi(CashPayRecordDO domain) {
		
		CashPayRecord entity = new CashPayRecord();
		
		ResultSupport result = BeanUtilsExtends.copy(entity, domain);
        if (!result.isSuccess())
        	return result;
        
        int r = -1;
        
        try {
            r = cashPayRecordMapper.updateByPrimaryKeySelective(entity);
        } catch (Exception e) {
        	e.printStackTrace();
        }
        
        if (r < 1) {
        	result.setSuccess(false);
        }
        
        return result;
	}

	public ResultDO remove(Integer id) {
		
		CashPayRecord entity = new CashPayRecord();
		
		ResultSupport result = new ResultSupport();
        if (!result.isSuccess())
        	return result;
        int r = -1;
        entity.setId(id);
        entity.setIsDelete(-1);
        try {
            r = cashPayRecordMapper.updateByPrimaryKeySelective(entity);
        } catch (Exception e) {
        	logger.error(ResultSupport.SYSTEM_EXCEPTION_ERROR_MSG + e.getMessage());
        }
        
        if (r < 1) {
        	result.setSuccess(false);
        }
        return result;
	}

	public ResultDO get(Integer id) {
		
		CashPayRecord entity = new CashPayRecord();

		ResultSupport result = new ResultSupport();
        if (!result.isSuccess())
        	return result;
        
        try {
        	entity = cashPayRecordMapper.selectByPrimaryKey(id);
        } catch (Exception e) {
        	e.printStackTrace();
        }
        
        if (entity==null) {
        	result.setSuccess(false);
        }
        
        CashPayRecordDO CashPayRecordDO = getCashPayRecordDO(entity);
        result.setModel(ResultSupport.FIRST_MODEL_KEY, CashPayRecordDO);
        return result;
	}
	
	public ResultDO dayStatistics(CashCashierDO cashCashierDO) {
		
		ResultSupport result = new ResultSupport();
		
		CashStatisticsDO  cashStatisticsDO = new CashStatisticsDO();
		
		SimpleDateFormat df = new SimpleDateFormat("YYYY-MM-dd");
		String start = df.format(cashCashierDO.getStartTimeStamp());
		String end = df.format(cashCashierDO.getEndTimeStamp());
		BigDecimal amount = new BigDecimal(0.00);
		BigDecimal cashAmount = new BigDecimal(0.00);
		BigDecimal accountAmount = new BigDecimal(0.00);
		Map<String, String> params = new HashMap<String, String>();
		PayMethodDO payMethodDO = new PayMethodDO();
		for(Integer key : PAY_METHOD_NAMES.keySet()) {
			params.put("cashierId", cashCashierDO.getId() + "");
			params.put("placeId", cashCashierDO.getPlaceId() + "");
			params.put("payMethodId", key + "");
			params.put("start", start );
			params.put("end", end );
			
			try {
				BigDecimal totle = cashPayRecordMapper.payMethodSum(params);
				System.out.println(cashCashierDO.getId() + " : " + cashCashierDO.getPlaceId() + " : " + key + "--------------------" + totle);
				if(totle == null) {
					totle = new BigDecimal(0.00);
				}
				if(key == 1) {
					
					payMethodDO.setAlipayAmount(totle);
				}
				if(key == 2) {
					payMethodDO.setWxPayAmount(totle);
				}
				if(key == 3) {
					cashAmount = cashAmount.add(totle);
					payMethodDO.setCashAmount(totle);
				}
				if(key == 4) {
					accountAmount = accountAmount.add(totle);
					payMethodDO.setAccountAmount(totle);
				}
				if(key == 5) {
					payMethodDO.setTransferAmount(totle);
				}
				amount = amount.add(totle);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		CashTypeDO cashTypeDO = new CashTypeDO();
		for(int key = 1; key <= 5; key++) {
			params.put("cashierId", cashCashierDO.getId() + "");
			params.put("placeId", cashCashierDO.getPlaceId() + "");
			params.put("cashType", key + "");
			params.put("start", start );
			params.put("end", end );
			try {
				BigDecimal totle = cashPayRecordMapper.cashTypeSum(params);
				if(totle == null) {
					totle = new BigDecimal(0.00);
				}
				if(key == 1) {
					cashTypeDO.setOrderAmount(totle);
				}
				if(key == 2) {
					cashTypeDO.setAddOrderAmount(totle);
				}
				if(key == 3) {
					cashTypeDO.setRechargeAmount(totle);
				}
				if(key == 4) {
					cashTypeDO.setOtherAmount(totle);
				}
				if(key == 5) {
					cashTypeDO.setMemberAmount(totle);
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		params = new HashMap<String, String>();
		params.put("cashierId", cashCashierDO.getId() + "");
		params.put("placeId", cashCashierDO.getPlaceId() + "");
		params.put("start", start );
		params.put("end", end );
		Integer cashCount = cashPayRecordMapper.countPayRecord(params);
	
		cashStatisticsDO.setAmount(amount);
		cashStatisticsDO.setCashierCount(cashCount);
		cashStatisticsDO.setCashAmount(cashAmount);
		cashStatisticsDO.setAccountAmount(accountAmount);
		cashStatisticsDO.setPayMethodDO(payMethodDO);
		cashStatisticsDO.setCashTypeDO(cashTypeDO);
		result.setModel(ResultSupport.FIRST_MODEL_KEY, cashStatisticsDO);
		return result;
	}

	@SuppressWarnings("deprecation")
	@Override
	public ResultDO dayStatistics1(CashCashierDO cashCashierDO) {
		
		ResultSupport result = new ResultSupport();
		
		if(cashCashierDO.getStartTimeStamp()==null||cashCashierDO.getEndTimeStamp()==null) {
			
			result.setErrorCode(ResultSupport.SYSTEM_EXCEPTION_ERROR);
			result.setErrorMsg(ResultSupport.SYSTEM_EXCEPTION_ERROR_MSG + "时间为空");
			result.setSuccess(false);
		}
		
		CashPayRecordExample example=new CashPayRecordExample();
		Criteria create = example.createCriteria();
		
		if(cashCashierDO.getPlaceId()!=null) {
			create.andPlaceIdEqualTo(cashCashierDO.getPlaceId());
		}
		if(cashCashierDO.getId()!=null) {
			create.andCashierIdEqualTo(cashCashierDO.getId());
		}
		
		create.andCreatetimeBetween(new Date(Long.parseLong(cashCashierDO.getStartTimeStamp())), new Date(Long.parseLong(cashCashierDO.getEndTimeStamp())+24*60*60*1000));
		
		CashStatisticsDO  cashStatisticsDO = new CashStatisticsDO();

		
		
		List<KeyValueDO> payMethod=new ArrayList<>();//支付方法分类统计
		KeyValueDO xj=new KeyValueDO();
		xj.setKey("现金");
		KeyValueDO yhk=new KeyValueDO();
		yhk.setKey("银行卡");
		KeyValueDO wx=new KeyValueDO();
		wx.setKey("微信");
		KeyValueDO zfb=new KeyValueDO();
		zfb.setKey("支付宝");
		KeyValueDO zz=new KeyValueDO();
		zz.setKey("转账");
		KeyValueDO hj2=new KeyValueDO();
		hj2.setKey("合计");
		
		KeyValueDO ye=new KeyValueDO();
		ye.setKey("余额支付");
		
	    List<KeyValueDO> cashType=new ArrayList<>(); //收银类型分类统计
	    
	    KeyValueDO dd=new KeyValueDO();
		dd.setKey("订单");
		KeyValueDO jx=new KeyValueDO();
		jx.setKey("加选");
		KeyValueDO cz=new KeyValueDO();
		cz.setKey("充值");
		KeyValueDO gm=new KeyValueDO();
		gm.setKey("购买会员");
		KeyValueDO qt=new KeyValueDO();
		qt.setKey("其他");
		KeyValueDO tk=new KeyValueDO();
		tk.setKey("退款");
		KeyValueDO hj1=new KeyValueDO();
		hj1.setKey("合计");
		
		BigDecimal amount = new BigDecimal(0.00);//总金额
		BigDecimal cashAmount = new BigDecimal(0.00);//现金
		BigDecimal accountAmount = new BigDecimal(0.00); //账户余额
		
		PayMethodDO payMethodDO=new PayMethodDO();
		CashTypeDO cashTypeDO=new CashTypeDO();
		try {
			List<CashPayRecord> data = cashPayRecordMapper.selectByExample(example);
			//次数
			cashStatisticsDO.setCount(data.size());
			for(CashPayRecord cpr:data) {
				BigDecimal amount2 = cpr.getAmount();
				if(cpr.getPayMethodId()==6) {
					//银行卡
					yhk.setValue(yhk.getValue().add(amount2));
					payMethodDO.setBankCardAmount(payMethodDO.getBankCardAmount().add(amount2));
				}
				if(cpr.getBillType()==0) {
					//退款
					tk.setValue(tk.getValue().add(amount2));
					cashTypeDO.setRefundAmount(cashTypeDO.getRefundAmount().add(amount2));
				}
				if(cpr.getPayMethodId()==5) {
					//转账
					zz.setValue(zz.getValue().add(amount2));
					payMethodDO.setTransferAmount(payMethodDO.getTransferAmount().add(amount2));
				}
				if(cpr.getBillType()==5) {
					//购买会员
					gm.setValue(gm.getValue().add(amount2));
					cashTypeDO.setMemberAmount(cashTypeDO.getMemberAmount().add(amount2));
				}
				if(cpr.getPayMethodId()==4) {
					//使用余额
					ye.setValue(ye.getValue().add(amount2));
					accountAmount=accountAmount.add(amount2);
					payMethodDO.setAccountAmount(payMethodDO.getAccountAmount().add(amount2));
				}
				if(cpr.getBillType()==4) {
					//其他金额
					qt.setValue(qt.getValue().add(amount2));
					cashTypeDO.setOtherAmount(cashTypeDO.getOtherAmount().add(amount2));
				}
				if(cpr.getPayMethodId()==3) {
					//使用现金
					xj.setValue(xj.getValue().add(amount2));
					cashAmount=cashAmount.add(amount2);
					payMethodDO.setCashAmount(payMethodDO.getCashAmount().add(amount2));
				}
				if(cpr.getBillType()==3) {
					//充值
					cz.setValue(cz.getValue().add(amount2));
					cashTypeDO.setRechargeAmount(cashTypeDO.getRechargeAmount().add(amount2));
				}
				
				if(cpr.getPayMethodId()==2) {
					//微信
					wx.setValue(wx.getValue().add(amount2));
					payMethodDO.setWxPayAmount(payMethodDO.getWxPayAmount().add(amount2));
				}
				if(cpr.getBillType()==2) {
					//订单
					jx.setValue(jx.getValue().add(amount2));
					cashTypeDO.setAddOrderAmount(cashTypeDO.getAddOrderAmount().add(amount2));
				}
				
				//总价格
				amount=amount.add(amount2);
				if(cpr.getPayMethodId()==1) {
					//支付宝
					zfb.setValue(zfb.getValue().add(amount2));
					payMethodDO.setAlipayAmount(payMethodDO.getAlipayAmount().add(amount2));
				}
				if(cpr.getBillType()==1) {
					dd.setValue(dd.getValue().add(amount2));
					cashTypeDO.setOrderAmount(cashTypeDO.getOrderAmount().add(amount2));
				}
			}
		} catch (Exception e) {
			result.setErrorCode(ResultSupport.SYSTEM_EXCEPTION_ERROR);
			result.setErrorMsg(ResultSupport.SYSTEM_EXCEPTION_ERROR_MSG + "查询失败");
			result.setSuccess(false);
		}
		cashStatisticsDO.setRealAmount(amount.subtract(accountAmount));
		//除开余额之和
		payMethodDO.setAmount(amount.subtract(accountAmount));
		//除开余额之和    收银类型
		cashTypeDO.setAmount(amount);
		
		//合计
		hj1.setValue(amount);
		hj2.setValue(amount);
		//总金额
		cashStatisticsDO.setAmount(amount);
		//现金
		cashStatisticsDO.setCashAmount(cashAmount);
		cashStatisticsDO.setAccountAmount(accountAmount);
		cashStatisticsDO.setPayMethodDO(payMethodDO);
		cashStatisticsDO.setCashTypeDO(cashTypeDO);
		payMethod.add(xj);
		payMethod.add(yhk);
		payMethod.add(wx);
		payMethod.add(zfb);
		payMethod.add(zz);
		payMethod.add(ye);
		payMethod.add(hj2);
		cashStatisticsDO.setPayMethod(payMethod);
		
		cashType.add(dd);
		cashType.add(jx);
		cashType.add(cz);
		cashType.add(gm);
		cashType.add(qt);
		cashType.add(tk);
		cashType.add(hj1);
		cashStatisticsDO.setCashType(cashType);
		
		
		result.setModel(ResultDO.FIRST_MODEL_KEY, cashStatisticsDO);
		return result;
	}

	
	public ResultDO query(CashPayRecordQueryDO query) {
		
		ResultSupport result = new ResultSupport();

		List<CashPayRecord> list = null;

		CashPayRecordExample example = new CashPayRecordExample();
		
		Criteria createCriteria = example.createCriteria();
		
		createCriteria.andIsDeleteEqualTo(1);
		long count = 0;
		if (query.isPage()) {
			example.setLimitByPage(query.getStart() + "," + query.getPageRows());
			count = cashPayRecordMapper.countByExample(example);
			result.setModel(ResultSupport.SECOND_MODEL_KEY, count);
		}
		
		List<CashPayRecordDO> doList = new ArrayList<CashPayRecordDO>();

		try {
			list = cashPayRecordMapper.selectByExample(example);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		BigDecimal totalAmount = new BigDecimal(0.00);
		
		for(CashPayRecord payRecord : list) {
			totalAmount = totalAmount.add(payRecord.getAmount());
		}

		doList = getCashPayRecordDOList(list);
		result.setModel(ResultSupport.FIRST_MODEL_KEY, doList);
		result.setModel(ResultSupport.THIRD_MODEL_KEY, totalAmount);
		return result;
	}
	
	public ResultDO query1(CashPayRecordQueryDO1 query) {
		
		ResultSupport result = new ResultSupport();

		List<CashPayRecord> list = null;

		CashPayRecordExample example = new CashPayRecordExample();
		
		Criteria create = example.createCriteria();
		
		Criteria create1 = example.or();
		
		if(query.getNameOrTel()!=null&&!"".equals(query.getNameOrTel())) {
			
			create.andCustomNameLike("%"+query.getNameOrTel()+"%");
			create1.andCustomTelLike("%"+query.getNameOrTel()+"%");
		}
		if(query.getOrderNO()!=null&&!"".equals(query.getOrderNO())) {
			create1.andOrderNOLike("%"+query.getOrderNO()+"%");
			create.andOrderNOLike("%"+query.getOrderNO()+"%");
		}
		if(query.getPayMethodId()!=null&&query.getPayMethodId()!=0) {
			create.andPayMethodIdEqualTo(query.getPayMethodId());
			create1.andPayMethodIdEqualTo(query.getPayMethodId());			
		}
		if(query.getInvoiceStatus()!=null&&!query.getInvoiceStatus().equals(0)) {
			create.andInvoiceStatusEqualTo(query.getInvoiceStatus());
			create1.andInvoiceStatusEqualTo(query.getInvoiceStatus());
		}
		if(query.getPlaceId()!=null&&!query.getPlaceId().equals(0)) {
			create1.andPlaceIdEqualTo(query.getPlaceId());
			create.andPlaceIdEqualTo(query.getPlaceId());
		}
		if(query.getCashierNameOrTel()!=null&&"".equals(query.getCashierNameOrTel())) {
			
			create.andCashierNameLike("%"+query.getCashierNameOrTel()+"%");
			create1.andCashierNameLike("%"+query.getCashierNameOrTel()+"%");
		}
		if(StringUtils.isNotEmpty(query.getStartTimeStamp()) &&
				StringUtils.isNotEmpty(query.getEndTimeStamp())) {
			
			Date startTime = new Date(Long.parseLong(query.getStartTimeStamp()));
			Date endTime = new Date((Long.parseLong(query.getEndTimeStamp()) + (24 * 60 * 60 * 1000)));
		
			create1.andCreatetimeBetween(startTime, endTime);
			create.andCreatetimeBetween(startTime, endTime);
		}
		if(query.getBillType()!=null&&!query.getBillType().equals(0)) {
			
			create.andBillTypeEqualTo(query.getBillType());
			create1.andBillTypeEqualTo(query.getBillType());
		}
		long count = 0;
		if (query.isPage()) {
			example.setLimitByPage(query.getStart() + "," + query.getPageRows());
			count = cashPayRecordMapper.countByExample(example);
			result.setModel(ResultSupport.SECOND_MODEL_KEY, count);
		}
		
		List<CashPayRecordDO> doList = new ArrayList<CashPayRecordDO>();

		try {
			list = cashPayRecordMapper.selectByExample(example);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		BigDecimal totalAmount = new BigDecimal(0.00);
		
		for(CashPayRecord payRecord : list) {
			totalAmount = totalAmount.add(payRecord.getAmount());
		}

		doList = getCashPayRecordDOList(list);
		result.setModel(ResultSupport.FIRST_MODEL_KEY, doList);
		result.setModel(ResultSupport.THIRD_MODEL_KEY, totalAmount);
		return result;
	}
	
	public CashPayRecordDO getCashPayRecordDO(CashPayRecord entity) {
		if (entity == null)
			return null;
		CashPayRecordDO dst = new CashPayRecordDO();
		return BeanUtilsExtends.copyProperties(dst, entity) ? dst : null;
	}
	public Properties getProperties() {
		InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("application.properties");
		Properties properties = new Properties();
		try {
			properties.load(inputStream);
		} catch (IOException e1) {
			return null;
		}
		return properties;
	}
	
	public List<CashPayRecordDO> getCashPayRecordDOList(List<CashPayRecord> list) {
		List<CashPayRecordDO> result = new ArrayList<CashPayRecordDO>();
		if (list != null && !list.isEmpty()) {
			for (CashPayRecord org : list) {
				CashPayRecordDO org1 = getCashPayRecordDO(org);
				if (org1 != null) {
					org1.setPdfPath(getProperties().getProperty("doc.download.path")+org1.getVoucherNO()+".pdf");
					org1.setCashTypeName(PAY_CASH_NAMES.get(org1.getCashType()));
					//获取销售员工信息
					com.jingyanzi.privilege.
						domain.result.ResultDO res = getEmployeeService().getEmployee(org.getCashierId());
					
					if(!res.isSuccess()) {
						return null;
					}
					EmployeeDO employeeDO = (EmployeeDO) res.getModel(ResultSupport.FIRST_MODEL_KEY);
					org1.setCashierName(employeeDO.getRealName());
					org1.setCreatetime(org.getCreatetime().getTime() + "");
					//要从字典查收款类型
					//获取字典信息
					com.jingyanzi.sys.domain
					.result.ResultDO res5 = getSettingService().getDictionariesById(org.getCashType());
					
					DictionariesDO dic = (DictionariesDO) res5.getModel(ResultSupport.FIRST_MODEL_KEY);
					
					org1.setCashTypeName(dic.getDataItem());
					result.add(org1);
				}
			}
		}
		return result;
	}

}
